import MSLogger
import WorkerMSDB
import MSDBTemplates
import heartbeating
import time
import os
import sys
import pdb

#we can put as MS IDs as PCN IDs
monitor_ids = ['605','642']
shouldReportUP=True
shouldReportDOWN=True
statusUP=False

MSLogger.logInit('C:\\safe\\ms.checker.log', 6, True)

if os.path.exists('c:\\safe\\ms.checker.pid'):
    MSLogger.logError('ms checker already running')
    sys.exit()
f = open('c:\\safe\\ms.checker.pid', 'w')
f.close()

def sendMSG(Msg):
    MSLogger.sendSMS(2, '+79119256529', Msg)
    MSLogger.logInfo('SMS: %s' % (str(Msg)))

def checkDaemonStatus():
    global shouldReportUP
    global shouldReportDOWN
    global statusUP

    s = heartbeating.HeartbeatSocket()
    pstatusUP = statusUP
    try:
        s.connect('localhost')
        s.ping()
        statusUP = True
    except:
        statusUP = False

    if pstatusUP == True and statusUP == False: shouldReportDOWN = True
    if pstatusUP == False and statusUP == True: shouldReportUP = True

    if shouldReportUP and statusUP:
        sendMSG('ms daemon is UP')
        shouldReportUP = False

    if shouldReportDOWN and not statusUP:
        sendMSG('ms daemon is DOWN')
        shouldReportDOWN = False

    return statusUP

def checkObjectStatus(Object):
    statusOn = False

    #normal continuous case
    if Object.lastEvent_PGSM and Object.preLastEvent_PGSM and Object.lastEvent_PGSM > Object.preLastEvent_PGSM:
        MSLogger.logInfo('object(%s:%s) normal continous' % (str(Object.objectPCNId), str(Object.objectMSId)))
        Object.preLastEvent_PGSM = Object.lastEvent_PGSM
        statusOn = True
        if Object.cameOOS:
             Object.cameOOS = False
             sendMSG('object(%s:%s) came back ONLINE' % (str(Object.objectPCNId), str(Object.objectMSId)))
    
    #continuous came down
    elif Object.lastEvent_PGSM and Object.preLastEvent_PGSM and not (Object.lastEvent_PGSM > Object.preLastEvent_PGSM):
        if Object.status:
             sendMSG('object(%s:%s) came OOS' % (str(Object.objectPCNId), str(Object.objectMSId)))
             Object.cameOOS = True
    
    #first execution case
    elif Object.lastEvent_PGSM and not Object.preLastEvent_PGSM:
        MSLogger.logInfo('object(%s:%s) normal first' % (str(Object.objectPCNId), str(Object.objectMSId)))
        Object.preLastEvent_PGSM = Object.lastEvent_PGSM
        statusOn = True

    #first execution and never online
    elif not Object.lastEvent_PGSM or not Object.preLastEvent_PGSM:
        sendMSG('object(%s:%s) is totally OOS' % (str(Object.objectPCNId), str(Object.objectMSId)))
    
    Object.eventsPGSM = []
    return statusOn

MSLogger.logInfo('ms checker started')

reader = WorkerMSDB.Worker('localhost', '2929', 'PGSMData', 'sa', 'safeinside')
reader.connect()

objects = []
MSDBTemplates.GET_MSObjects_FROM_CarOnline(reader.connection.cursor(), objects)

monobjects = [] #to be monitored

for o in objects:
    if str(o.objectMSId) in monitor_ids or str(o.objectPCNId) in monitor_ids:
        o.preLastEvent_PGSM = None
        monobjects.append(o)

try:
    while True:
        #1 Check car-online
        cursor = reader.connection.cursor()
        for o in monobjects:
            query = 'SELECT TOP(1) id,eventTime,type FROM _event_data_internal WHERE deviceId=%s ORDER BY eventTime DESC' % (str(o.objectMSId))
            cursor.execute(query)
            d = cursor.fetchall()
            o.lastEvent_PGSM = d[0][1]
            o.status = checkObjectStatus(o)

        #2 Check daemon
        dstatus = checkDaemonStatus()

        time.sleep(600)
except KeyboardInterrupt:
    MSLogger.logError('ms checker stopped')
    os.unlink('c:\\safe\\ms.checker.pid')
except Exception, err:
    shr = str(err)[0:100]
    MSLogger.logError('ms checker fatal error: %s' % (str(err)))
    os.unlink('c:\\safe\\ms.checker.pid')
